home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / kill / kill.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-11  |  4.8 KB  |  212 lines

  1. /* 
  2.  * kill.c --
  3.  *
  4.  *    A program to send a signal to a process or process group.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/cmds/kill/RCS/kill.c,v 1.6 90/11/11 12:31:59 kupfer Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <ctype.h>
  21. #include <errno.h>
  22. #include <option.h>
  23. #include <signal.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. /*
  29.  * Variables and tables used to parse command-line options:
  30.  */
  31.  
  32. int sendToGroup = 0;
  33. int printSignals = 0;
  34. int signalNumber = SIGTERM;
  35.  
  36. Option optionArray[] = {
  37.     {OPT_DOC, (char *) NULL, (char *) NULL,
  38.         "kill [-sig] [options] pid pid ..."},
  39.     {OPT_DOC, (char *) NULL, (char *) NULL,
  40.         "\"Sig\" may be either a signal name or a number (default: TERM).\n"},
  41.     {OPT_TRUE, "g", (char *) &sendToGroup,
  42.         "Send signal to group instead of single process"},
  43.     {OPT_TRUE, "l", (char *) &printSignals,
  44.         "Print out list of valid signal names"}
  45. };
  46.  
  47. /*
  48.  * Printable names and identifying messages for all signals, indexed by
  49.  * signal number.
  50.  */
  51.  
  52. struct    info {
  53.     char    *name;
  54.     char    *reason;
  55. } info[] = {
  56.     0, 0,
  57.     "HUP",        "Hangup",
  58.     "INT",        "Interrupt",
  59.     "DEBUG",    "Debug",
  60.     "ILL",        "Illegal instruction",
  61.     0,        "Signal 5",
  62.     "IOT",        "IOT instruction",
  63.     "EMT",        "EMT instruction",
  64.     "FPE",        "Floating-point exception",
  65.     "KILL",        "Killed",
  66.     "MIG",        "Migrated",
  67.     "SEGV",        "Segmentation violation",
  68.     0,        "Signal 12",
  69.     "PIPE",        "Broken pipe",
  70.     "ALRM",        "Alarm clock",
  71.     "TERM",        "Software termination",
  72.     "URG",        "Urgent I/O condition",
  73.     "STOP",        "Suspended (signal)",
  74.     "TSTP",        "Suspended",
  75.     "CONT",        "Continued",
  76.     "CHLD",        "Child status changed",
  77.     "TTIN",        "Suspended (tty input)",
  78.     0,        "Signal 22",
  79.     "IO",        "I/O is possible on a descriptor",
  80.     0,        "Signal 24",
  81.     0,        "Signal 25",
  82.     0,        "Signal 26",
  83.     0,        "Signal 27",
  84.     "WINCH",    "Window changed",
  85.     "MIGHOME",    "Migrated home",
  86.     "USR1",        "User-defined signal 1",
  87.     "USR2",        "User-defined signal 2",
  88.     0,        "Signal 32",
  89. };
  90.  
  91. /*
  92.  *----------------------------------------------------------------------
  93.  *
  94.  * main --
  95.  *
  96.  *    Main program for "kill".
  97.  *
  98.  * Results:
  99.  *    None.
  100.  *
  101.  * Side effects:
  102.  *    See the man page for details.
  103.  *
  104.  *----------------------------------------------------------------------
  105.  */
  106.  
  107. main(argc, argv)
  108.     int argc;
  109.     char **argv;
  110. {
  111.     int i, j, newArgc;
  112.     int result = 0;
  113.     char *sigName, *endPtr;
  114.     char scratch[10];
  115.  
  116.     /*
  117.      * Make a pass over the options to suck up the signal number or name.
  118.      * Then call Opt_ to parse the remaining options.
  119.      */
  120.  
  121.     for (i = 1, newArgc = 1; i < argc; i++) {
  122.     char *p;
  123.  
  124.     p = argv[i];
  125.     if (*p != '-') {
  126.         argv[newArgc] = argv[i];
  127.         newArgc++;
  128.         continue;
  129.     }
  130.     p++;
  131.     if (isdigit(*p)) {
  132.         signalNumber = strtoul(p, &endPtr, 0);
  133.         if (*endPtr != 0) {
  134.         (void) fprintf(stderr, "Bad signal number \"%s\".\n", p);
  135.         exit(1);
  136.         }
  137.     } else {
  138.         for (j = 1; j <= 32; j++) {
  139.         if ((info[j].name != 0) && (strcmp(p, info[j].name) == 0)) {
  140.             signalNumber = j;
  141.             break;
  142.         }
  143.  
  144.         /*
  145.          * If this switch didn't match a signal name, save the
  146.          * argument for Opt_ processing.
  147.          */
  148.  
  149.         if (j == 32) {
  150.             argv[newArgc] = argv[i];
  151.             newArgc++;
  152.         }
  153.         }
  154.     }
  155.     }
  156.     argc = Opt_Parse(newArgc, argv, optionArray, Opt_Number(optionArray), 0);
  157.  
  158.     /*
  159.      * If the user just wants a list of signals, print it and quit.
  160.      */
  161.  
  162.     if (printSignals) {
  163.     for (i = 0; i < 32; i++) {
  164.         if (info[i].name == 0) {
  165.         continue;
  166.         }
  167.         (void) printf("%2d  %-15s %s\n", i, info[i].name, info[i].reason);
  168.     }
  169.     exit(0);
  170.     }
  171.  
  172.     if (argc == 1) {
  173.     (void) fprintf(stderr, "Usage:  %s [options] pid pid ...\n", argv[0]);
  174.     exit(1);
  175.     }
  176.  
  177.     if (signalNumber <= 32) {
  178.     sigName = info[signalNumber].name;
  179.     } else {
  180.     (void) sprintf(scratch, "Signal %d", signalNumber);
  181.     sigName = scratch;
  182.     }
  183.  
  184.     for (i = 1; i < argc; i++) {
  185.     int pid;
  186.     char *endPtr;
  187.  
  188.     pid = strtoul(argv[i], &endPtr, 16);
  189.     if ((endPtr == argv[i]) || (*endPtr != 0)) {
  190.         (void) fprintf(stderr, "Bad process id \"%s\";  ignoring.\n", argv[i]);
  191.         continue;
  192.     }
  193.  
  194.     if (sendToGroup) {
  195.         if (killpg(pid, signalNumber) != 0) {
  196.             (void) fprintf(stderr,
  197.                 "Couldn't send %s signal to group 0x%x: %s.\n",
  198.                 sigName, pid, strerror(errno));
  199.         }
  200.         result = 1;
  201.     } else {
  202.         if (kill(pid, signalNumber) != 0) {
  203.             (void) fprintf(stderr,
  204.                 "Couldn't send %s signal to process 0x%x: %s.\n",
  205.                 sigName, pid, strerror(errno));
  206.         }
  207.         result = 1;
  208.     }
  209.     }
  210.     return result;
  211. }
  212.